package Frame.battleanimation;

import FCRendering.FCRMaster;
import VWorldGameStudio.FCAnimation;

import java.awt.*;
import java.util.ArrayList;

import static FCRendering.FCRMaster.fcv;

/**
 * bpbwan
 * 带有准备侦的攻击方式
 */
public class AttackReadyFrameModeAni extends ABattleAni implements IBattleAni {

    ArrayList<ChildAni> childAnis = new ArrayList<>();
    private int oneChildFireTime = 12;
    protected int readyFrame = 8;

    private boolean isNeedRecoilWhenShot = false;//是否要后坐力一下
    private int addStartFrame = 9;//持炮停留时间
    public AttackReadyFrameModeAni(FCAnimation ani, int[] startPoint, int[] endpoint, boolean isPlayerAttackMode, boolean hasReadyFrame
    , boolean isPao) {
        if (!hasReadyFrame) {
            readyFrame = 0;
        }
        if (isPlayerAttackMode) {
            playerOffset[0] = (int) (20 * fcv.getProportion());
            startPoint[0] -= playerOffset[0];
        } else {
            playerOffset[0] = (int) (40 * fcv.getProportion());
            startPoint[0] += playerOffset[0];
        }
        for (int i = 0; i < endpoint.length / 2; i++) {
            int[] endp = new int[2];
            endp[0] = endpoint[i * 2];
            endp[1] = endpoint[i * 2 + 1];
            int[] start = new int[2];
            start[0] = startPoint[0];
            start[1] = startPoint[1];
            ChildAni c = new ChildAni(ani, start, endp, isPlayerAttackMode, this, oneChildFireTime * i);
            if(c.startFrame <= 1 && isPao){
                isNeedRecoilWhenShot = true;
                c.startFrame = addStartFrame;
            }
            if(!hasReadyFrame){
                oneChildFireTime = c.startFrame + 5;
            }
            childAnis.add(c);
        }
        //拔刀
        allFrames = childAnis.get(0).allFrames + oneChildFireTime * (childAnis.size() - 1);
    }


    public void nextFrame(int frame) {
        ChildAni lastOne = null;
        for (ChildAni childAni : childAnis) {
            if (childAni.whenStartFrame <= frame) {
                childAni.nextFrame(frame - childAni.whenStartFrame);
            }
            lastOne = childAni;
        }
        //TODO 收刀动作
        if (frame > lastOne.whenStartFrame + oneChildFireTime) {
            attackReadyState = true;
        }
    }

    @Override
    public void paintBattleSceen(Graphics g, FCRMaster fcrMaster) {
        for (ChildAni childAni : childAnis) {
            childAni.paintBattleSceen(g, fcrMaster);
        }
    }


    @Override
    public void fire(Graphics g, FCRMaster fcrMaster) {
    }

    @Override
    public void flying(Graphics g, FCRMaster fcrMaster) {
    }

    @Override
    public void boom(Graphics g, FCRMaster fcrMaster) {
    }


    protected class ChildAni extends ABattleAni {
        //原点
        protected int[] startPoint;
        //结束点
        protected int[] endPoints;
        protected FCAnimation animation;

        protected int startFrame = 0;
        protected int flyFrame = 0;
        protected int boomFrame = 0;
        protected int[] firePaintPoints = new int[2];
        protected int[] paintPoints = new int[2];
        protected int[] tmpPoint = new int[2];
        protected int startPngIndex = -1;
        protected int flyPngIndex = -1;
        protected int boomPngIndex = -1;
        protected double targetDistance;
        private int endFrame = 5;
        boolean hited = true;//打中的
        ABattleAni parent;
        protected int whenStartFrame = 0;
        protected int insideCountFrame = 0;
        public ChildAni(FCAnimation ani, int[] startPoint, int[] endpoint, boolean isPlayerAttackMode, ABattleAni parent, int whenStartFrame) {
            this.parent = parent;
            this.animation = ani;
            this.startPoint = startPoint;
            this.endPoints = endpoint;
            this.whenStartFrame = whenStartFrame;
            if (endpoint[0] <= 0 || endpoint[0] >= (int) (1920 * fcv.getProportion())) {
                hited = false;//没打着
            }
            this.isPlayerAttackMode = isPlayerAttackMode;
            if (ani.getFirePngUrl().size() > 0) {
                startFrame = ani.fireFrameTime / 16;
                if (ani.getFirePngUrl().size() > startFrame) {
                    startFrame = ani.getFirePngUrl().size();
                }
            }
            if (ani.getFlyingPngUrl().size() > 0) {
                //STEP 1计算俩点之间距离，速度假设是v像素/毫秒，
                int v = (int) (600 * fcv.getProportion());
                targetDistance = AnimationUtil.getDistance(startPoint, endpoint);
                flyFrame = (int) (16 * targetDistance / v);
            }
            if (ani.getBoomPngUrl().size() > 0) {
                boomFrame = ani.boomFrameTime / 16;
                if (ani.getBoomPngUrl().size() > boomFrame) {
                    boomFrame = ani.getBoomPngUrl().size();
                }
            }
            System.out.println("startFrame "+startFrame);
            this.allFrames = boomFrame + flyFrame + startFrame + endFrame + readyFrame;
        }

        @Override
        public void nextFrame(int frame) {
            insideCountFrame++;
            if (frame < readyFrame) {
                parent.attackReadyState = true;
                attackReadyState = true;
            } else {
                if (attackReadyState) {
                    attackReadyState = false;
                    parent.attackReadyState = false;
                }
                frame -= readyFrame;
                if (frame <= startFrame && startFrame != 0) {
                    int p = startFrame / animation.getFirePngUrl().size();
                    int index = frame / p + 1;
                    firePaintPoints[0] = startPoint[0] + (int) (animation.firePngCenterOffsetX * fcv.getProportion());
                    firePaintPoints[1] = startPoint[1] + (int) (animation.firePngCenterOffsetY * fcv.getProportion());
                    startPngIndex = Math.min(index, animation.getFirePngUrl().size() - 1);
                } else {
                    startPngIndex = -1;
                }
                if (flyFrame != 0 && (isNeedRecoilWhenShot?frame > startFrame:(frame > startFrame - 10)) && frame < (startFrame + flyFrame)) {
                    int p = flyFrame / animation.getFlyingPngUrl().size();
                    int index = (frame - startFrame) / p + 1;
                    flyPngIndex = Math.min(index, animation.getFlyingPngUrl().size() - 1);
                    flyPngIndex = Math.max(flyPngIndex, 0);

                    if (frame <= startFrame && startFrame != 0) {
                        //从枪口射出
                        paintPoints[0] = startPoint[0] + (int) (animation.flyingPngCenterOffsetX * fcv.getProportion());
                        paintPoints[1] = startPoint[1] + (int) (animation.flyingPngCenterOffsetY * fcv.getProportion());
                    } else {
                        AnimationUtil.getAnimatePoint(paintPoints, startPoint, endPoints, (float) (frame - startFrame) / flyFrame);
                        paintPoints[0] = paintPoints[0] + (int) (animation.flyingPngCenterOffsetX * fcv.getProportion());
                        paintPoints[1] = paintPoints[1] + (int) (animation.flyingPngCenterOffsetY * fcv.getProportion());
                        //   System.out.println("paintPoints "+paintPoints[0]+"*"+paintPoints[1]);
                    }
                   // System.out.println("isNeedRecoilWhenShot "+isNeedRecoilWhenShot+" "+insideCountFrame);
                    if(isNeedRecoilWhenShot){
                        if(insideCountFrame == addStartFrame + 2){
                            if (parent.isPlayerAttackMode) {
                                parent.playerOffset[0] = (int) (14 * fcv.getProportion());
                            }
                        }else if(insideCountFrame == addStartFrame + 4){
                            if (parent.isPlayerAttackMode) {
                                parent.playerOffset[0] = (int) (8 * fcv.getProportion());
                            }
                        }else if(insideCountFrame == addStartFrame + 6){
                            if (parent.isPlayerAttackMode) {
                                parent.playerOffset[0] = (int) (2 * fcv.getProportion());
                            }
                        }else if(insideCountFrame == addStartFrame + 10){
                            if (parent.isPlayerAttackMode) {
                                parent.playerOffset[0] = (int) (8 * fcv.getProportion());
                            }
                        }else if(insideCountFrame == addStartFrame + 12){
                            if (parent.isPlayerAttackMode) {
                                parent.playerOffset[0] = (int) (14 * fcv.getProportion());
                            }
                        }else if(insideCountFrame == addStartFrame + 14){
                            if (parent.isPlayerAttackMode) {
                                parent.playerOffset[0] = (int) (20 * fcv.getProportion());
                            }
                        }
                    }
                } else if (boomFrame != 0 && frame >= (startFrame + flyFrame) && frame <= (allFrames - endFrame)) {
                    flyPngIndex = -1;
                    int p = boomFrame / animation.getBoomPngUrl().size();
                    int index = (frame - flyFrame - startFrame) / p + 1;
                    boomPngIndex = Math.min(index, animation.getBoomPngUrl().size() - 1);
                    boomPngIndex = Math.max(boomPngIndex, 0);
                    tmpPoint[0] = endPoints[0] + (int) (animation.boomPngCenterOffsetX * fcv.getProportion());
                    tmpPoint[1] = endPoints[1] + (int) (animation.boomPngCenterOffsetY * fcv.getProportion());
                    if (animation.getBoomPngScales() != 1) {
                        double dw = (animation.getBoomPngScales() - 1) * animation.boomPngSizeW * fcv.getProportion();
                        double dh = (animation.getBoomPngScales() - 1) * animation.boomPngSizeH * fcv.getProportion();
                        tmpPoint[0] -= (int) (dw / 2);
                        tmpPoint[1] -= (int) (dh / 2);
                    }
                    paintPoints[0] = tmpPoint[0];
                    paintPoints[1] = tmpPoint[1];
                } else if (frame > (allFrames - endFrame)) {
                    startPngIndex = -1;
                    flyPngIndex = -1;
                    boomPngIndex = -1;
                }
            }
        }

        @Override
        public void paintBattleSceen(Graphics g, FCRMaster fcrMaster) {
            if (startPngIndex != -1) {
                g.drawImage(animation.getFirePng().get(startPngIndex), firePaintPoints[0], firePaintPoints[1],
                        (int) (animation.firePngSizeW * fcv.getProportion()), (int) (animation.firePngSizeH * fcv.getProportion()), fcrMaster);
            }
            if (flyPngIndex != -1) {
                g.drawImage(animation.getFlyingPng().get(flyPngIndex), paintPoints[0], paintPoints[1],
                        (int) (animation.flyingPngSizeW * fcv.getProportion()), (int) (animation.flyingPngSizeH * fcv.getProportion()), fcrMaster);
            } else if (boomPngIndex != -1) {
                g.drawImage(animation.getBoomPng().get(boomPngIndex), paintPoints[0], paintPoints[1],
                        (int) (animation.getBoomPngScales() * animation.boomPngSizeW * fcv.getProportion()),
                        (int) (animation.getBoomPngScales() * animation.boomPngSizeH * fcv.getProportion()), fcrMaster);
            }
        }
    }
}
